package com.doudou.oauth.exception;

import com.doudou.oauth.constant.ExceptionCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.security.oauth2.provider.error.DefaultWebResponseExceptionTranslator;

/**
 * @Author: 傻男人
 * @Date: 2020/5/8 16:06
 * @Version: 1.0
 * @Description: 异常处理
 */
@Slf4j
public class SimpleWebResponseExceptionTranslator extends DefaultWebResponseExceptionTranslator {

    public ResponseEntity translate(Exception e) throws Exception {
        ResponseEntity<OAuth2Exception> responseEntity = super.translate(e);
        return handlerResponseEntity(responseEntity);
    }


    public ResponseEntity<OAuth2Exception> handlerResponseEntity( ResponseEntity<OAuth2Exception> responseEntity){
        OAuth2Exception exception = responseEntity.getBody();
        OAuth2Exception ex = handlerOAuth2Exception(exception);
        return new ResponseEntity<OAuth2Exception>(ex
                ,responseEntity.getHeaders(),responseEntity.getStatusCode());
    }

    private OAuth2Exception handlerOAuth2Exception(OAuth2Exception exception) {
        String errorCode = exception.getOAuth2ErrorCode();
        String errorMessage = exception.getMessage();

        if ("invalid_client".equals(errorCode)) {
            if(errorMessage.contains("Unauthorized grant type")){
                return createOAuth2Exception(ExceptionCode.invalid_grant, "授权类型不支持", errorCode);
            }
            return createOAuth2Exception(ExceptionCode.invalid_client, "非法应用", errorCode);
        }
        else if ("unauthorized_client".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.unauthorized_client, "应用未授权", errorCode);
        }
        else if ("invalid_grant".equals(errorCode)) {
            if (errorMessage.toLowerCase().contains("redirect") && errorMessage.toLowerCase().contains("match")) {
                return createOAuth2Exception(ExceptionCode.invalid_grant, "redirect 不正确或者 (not match)", errorCode);
            } else {
                return createOAuth2Exception(ExceptionCode.invalid_grant, "非法授权参数", errorCode);
            }
        }
        else if ("invalid_scope".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.invalid_scope, "非法scope", errorCode);
        }
        else if ("invalid_token".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.invalid_token, "非法token", errorCode);
        }
        else if ("invalid_request".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.invalid_request, "非法请求方法", errorCode);
        }
        else if ("redirect_uri_mismatch".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.redirect_uri_mismatch, "redirect URI不匹配", errorCode);
        }
        else if ("unsupported_grant_type".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.unsupported_grant_type, "不支持的授权类型", errorCode);
        }
        else if ("unsupported_response_type".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.unsupported_response_type, "不支持返回类型", errorCode);
        }
        else if ("insufficient_scope".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.insufficient_scope, "需要scope", errorCode);
        }
        else if ("access_denied".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.access_denied, "禁止访问", errorCode);
        }
        else if ("unauthorized".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.unauthorized, "错误的认证", errorCode);
        }else if ("method_not_allowed".equals(errorCode)) {
            return createOAuth2Exception(ExceptionCode.method_not_allowed, "不支持请求", errorCode);
        }
        return createOAuth2Exception(ExceptionCode.INTERNAL_SERVER_ERROR, "系统错误", "server_error");
    }


    private OAuth2Exception createOAuth2Exception(Integer code, String msg, String errorCode){
        OAuth2Exception auth2Exception = OAuth2Exception.create(errorCode,msg);
        auth2Exception.addAdditionalInformation("code",String.valueOf(code));
        return  auth2Exception;
    }

}